
#pragma once

#include <string.h>
#include <set>
#include <system_error>
#include "../TcpConn.h"
#include "../../common/platform.h"
#include "../../tlsconfig/TLSConfig.h"
#include "../../common/ServerStatus.h"

class Listener;
class LoopService;
class LoopThreadPool;

class TCPServer : public TcpConnHandleBase, public ServerStatus
{
public:
    explicit TCPServer(int thread_num);
    ~TCPServer();

    LoopService* loop() {
        return loop_;
    }

    std::error_code listen(const std::string& addr, const TLSConfigPtr& tls);

    std::error_code run();

    void stop();
private:
    void accept_handle(ez_socket_t fd, const struct sockaddr *addr, int socklen);

    void tcp_conn_close_handle(const TcpConnPtr& conn);
private:
    std::shared_ptr<Listener>   listener_;
    LoopService                 *loop_;
    std::shared_ptr<LoopThreadPool> pool_;

    //////////////////////////////////////////////////////////////////////////
    std::set<TcpConnPtr>   connections_;
    TLSConfigPtr            tls_config_;
};